package com.hd123.rumba.gwt.widget2.client.grid;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.hd123.rumba.gwt.widget2.client.misc.RImageLocation;
import com.hd123.rumba.gwt.widget2.client.toolbar.RToolbar;
import com.hd123.rumba.gwt.widget2.client.toolbar.RToolbarButton;
import com.hd123.rumba.gwt.widget2.client.toolbar.RToolbarSeperator;

/**
 * 翻页工具栏
 * 
 * @author LiQi
 * 
 */
public class RPagingBar extends RToolbar {

  /** 样式 */
  private static final String STYLENAME = "rb-Pagingbar";

  /** 按钮图片地址 */
  private static final String IMAGE_URL_FIRSTPAGE = "images/grid/page-first.gif";
  private static final String IMAGE_URL_FIRSTPAGE_DISABLED = "images/grid/page-first-disabled.gif";
  private static final String IMAGE_URL_PREVPAGE = "images/grid/page-prev.gif";
  private static final String IMAGE_URL_PREVPAGE_DISABLED = "images/grid/page-prev-disabled.gif";
  private static final String IMAGE_URL_NEXTPAGE = "images/grid/page-next.gif";
  private static final String IMAGE_URL_NEXTPAGE_DISABLED = "images/grid/page-next-disabled.gif";
  private static final String IMAGE_URL_LASTPAGE = "images/grid/page-last.gif";
  private static final String IMAGE_URL_LASTPAGE_DISABLED = "images/grid/page-last-disabled.gif";

  private static final String IMAGE_URL_WAITING = "images/grid/wait.gif";
  private static final String IMAGE_URL_WAITING_DISABLED = "images/grid/done.gif";

  /** 分页表格 */
  private RPagingGrid pagingGrid;

  /** 数据表格 */
  private RGrid grid;

  /** 数据提供者 */
  private RGridPageDataProvider provider;

  /** 翻页按钮 */
  private RToolbarButton firstPage, prevPage, nextPage, lastPage;

  /** 是否显示按钮标题 */
  private boolean showButtonText = true;

  /** 当前页编辑框 */
  private TextBox currentPageBox;

  /** 总页数标签 */
  private Label pageCountLabel;

  /** 等待图标 */
  private Image waiting;

  /** 每页记录数面板 */
  private HorizontalPanel pageSizePanel;

  /** 每页记录数下拉框 */
  private ListBox pageSizeBox;

  /** 是否显示每页记录数 */
  private boolean showPageSizeBox = true;

  /** 总记录数和当前显示的记录数标签 */
  private Label recLabel;

  /** 每页记录数已改变 */
  private boolean pageSizeChanged = false;

  public RPagingBar(RPagingGrid pagingGrid, RGridPageDataProvider provider) {
    super();

    this.pagingGrid = pagingGrid;
    this.grid = pagingGrid.getGrid();
    this.provider = provider;

    addStyleName(STYLENAME);
    buildUI();
  }

  /**
   * 构造界面
   * 
   */
  private void buildUI() {
    PagingButtonHandler pagingButtonHandler = new PagingButtonHandler();
    Label label;

    // 第一页按钮
    firstPage = new RToolbarButton("首页", pagingButtonHandler);
    firstPage.setIcon(new RImageLocation(IMAGE_URL_FIRSTPAGE));
    firstPage.setDisabledIcon(new RImageLocation(IMAGE_URL_FIRSTPAGE_DISABLED));
    add(firstPage);

    // 前一页按钮
    prevPage = new RToolbarButton("上页", pagingButtonHandler);
    prevPage.setIcon(new RImageLocation(IMAGE_URL_PREVPAGE));
    prevPage.setDisabledIcon(new RImageLocation(IMAGE_URL_PREVPAGE_DISABLED));
    add(prevPage);

    // 当前页信息
    add(new RToolbarSeperator());

    label = new Label("第");
    label.setWidth("14px");
    label.setHorizontalAlignment(HasAlignment.ALIGN_LEFT);
    add(label);

    currentPageBox = new TextBox();
    currentPageBox.setWidth("24px");
    CurrentPageBoxHandler currentPageBoxHandler = new CurrentPageBoxHandler();
    currentPageBox.addClickHandler(currentPageBoxHandler);
    currentPageBox.addKeyDownHandler(currentPageBoxHandler);
    add(currentPageBox);

    label = new Label("页");
    label.setWidth("14px");
    label.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT);
    add(label);

    add(new Label("，共"));

    pageCountLabel = new Label("0");
    DOM.setStyleAttribute(pageCountLabel.getElement(), "padding", "0px 3px 0px 3px");
    add(pageCountLabel);

    add(new Label("页"));
    add(new RToolbarSeperator());

    // 下一页按钮
    nextPage = new RToolbarButton("下页", pagingButtonHandler);
    nextPage.setIcon(new RImageLocation(IMAGE_URL_NEXTPAGE));
    nextPage.setDisabledIcon(new RImageLocation(IMAGE_URL_NEXTPAGE_DISABLED));
    add(nextPage);

    //最后一页按钮
    lastPage = new RToolbarButton("尾页", pagingButtonHandler);
    lastPage.setIcon(new RImageLocation(IMAGE_URL_LASTPAGE));
    lastPage.setDisabledIcon(new RImageLocation(IMAGE_URL_LASTPAGE_DISABLED));
    add(lastPage);

    // 等待图标
    add(new RToolbarSeperator());
    waiting = new Image(IMAGE_URL_WAITING_DISABLED);
    waiting.setSize("18px", "18px");
    add(waiting);
    add(new RToolbarSeperator());

    // 每页记录数
    pageSizePanel = new HorizontalPanel();
    add(pageSizePanel);

    label = new Label("每页显示");
    label.setWidth("50px");
    pageSizePanel.add(label);
    pageSizePanel.setCellVerticalAlignment(label, HasAlignment.ALIGN_MIDDLE);

    pageSizeBox = new ListBox();
    pageSizeBox.addItem("5");
    pageSizeBox.addItem("10");
    pageSizeBox.addItem("20");
    pageSizeBox.addItem("50");
    pageSizeBox.addItem("100");
    pageSizeBox.addChangeHandler(new PageSizeBoxHandler());
    pageSizePanel.add(pageSizeBox);

    label = new Label("条");
    label.setWidth("14px");
    label.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT);
    pageSizePanel.add(label);
    pageSizePanel.setCellVerticalAlignment(label, HasAlignment.ALIGN_MIDDLE);

    // 记录数信息
    recLabel = new Label("");
    DOM.setStyleAttribute(recLabel.getElement(), "padding", "0px 5px 0px 0px");
    add(recLabel, RToolbar.ALIGN_RIGHT);
  }

  /**
   * 执行翻页动作
   * 
   * @param page
   *          页序号，从0计数
   */
  public void gotoPage(int page) {
    showLoading();

    // 记录分页表格高度信息，以备调整
    final int oldRowCount = provider.getRowCount();
    final int oldHeight = DOM.getElementPropertyInt(pagingGrid.getElement(), "offsetHeight");

    provider.fetch(page, new AsyncCallback() {
      public void onFailure(Throwable caught) {
        showLoaded();
      }

      public void onSuccess(Object result) {
        showLoaded();
        if (!((Boolean) result).booleanValue())
          return;

        if (grid.isBuild())
          grid.refresh();
        else
          grid.rebuild();
        grid.deselectAllRows();

        // 当行数减少并且每页记录数没有改变时，保持整个pagingGrid的高度不变
        if (provider.getRowCount() < oldRowCount && !pageSizeChanged)
          pagingGrid.setHeight(new Integer(oldHeight).toString() + "px");
        else
          pagingGrid.setHeight("");

        pageSizeChanged = false;
        refresh();

        // 触发pageLoad事件
        pagingGrid.firePageLoad();
      }
    });
  }

  /**
   * 界面显示正在加载数据
   * 
   */
  private void showLoading() {
    waiting.setUrl(IMAGE_URL_WAITING);
  }

  /**
   * 界面显示数据已经加载完成
   * 
   */
  private void showLoaded() {
    waiting.setUrl(IMAGE_URL_WAITING_DISABLED);
  }

  /**
   * 是否显示按钮标题
   * 
   * @return
   */
  public boolean isShowButtonText() {
    return showButtonText;
  }

  /**
   * 设置是否显示按钮标题
   * 
   * @param showButtonText
   */
  public void setShowButtonText(boolean showButtonText) {
    this.showButtonText = showButtonText;

    firstPage.setShowText(this.showButtonText);
    prevPage.setShowText(this.showButtonText);
    nextPage.setShowText(this.showButtonText);
    lastPage.setShowText(this.showButtonText);
  }

  /**
   * 是否显示每页记录数，默认为true
   * 
   * @return
   */
  public boolean isShowPageSizeBox() {
    return showPageSizeBox;
  }

  /**
   * 设置是否显示每页记录数
   * 
   * @param showPageSizeBox
   */
  public void setShowPageSizeBox(boolean showPageSizeBox) {
    if (this.showPageSizeBox == showPageSizeBox)
      return;

    this.showPageSizeBox = showPageSizeBox;
    pageSizePanel.setVisible(showPageSizeBox);
  }

  /**
   * 刷新当前页、记录数等信息
   * 
   */
  private void refresh() {
    firstPage.setEnabled(provider.getCurrentPage() > 0);
    prevPage.setEnabled(provider.getCurrentPage() > 0);
    nextPage.setEnabled(provider.getCurrentPage() < provider.getPageCount() - 1);
    lastPage.setEnabled(provider.getCurrentPage() < provider.getPageCount() - 1);

    currentPageBox.setText(new Integer(provider.getCurrentPage() + 1).toString());
    pageCountLabel.setText(new Integer(provider.getPageCount()).toString());

    for (int i = 0; i < pageSizeBox.getItemCount(); i++) {
      if (pageSizeBox.getItemText(i).equals(new Integer(provider.getPageSize()).toString()))
        pageSizeBox.setSelectedIndex(i);
    }

    if (provider.getTotalCount() > 0) {
      int startRec = provider.getCurrentPage() * provider.getPageSize() + 1;
      int endRec = provider.getCurrentPage() * provider.getPageSize() + provider.getRowCount();
      recLabel.setText("当前显示 " + startRec + " - " + endRec + "，共 " + provider.getTotalCount()
          + " 条");
    } else {
      recLabel.setText("没有数据");
    }
  }

  /**
   * 翻页按钮事件处理
   * 
   * @author LiQi
   * 
   */
  private class PagingButtonHandler implements ClickHandler {
    public void onClick(ClickEvent event) {
      if (event.getSource().equals(firstPage)) {
        gotoPage(0);
        return;
      }

      if (event.getSource().equals(prevPage)) {
        if (provider.getCurrentPage() > 0)
          gotoPage(provider.getCurrentPage() - 1);
        return;
      }

      if (event.getSource().equals(nextPage)) {
        if (provider.getCurrentPage() < provider.getPageCount() - 1)
          gotoPage(provider.getCurrentPage() + 1);
        return;
      }

      if (event.getSource().equals(lastPage)) {
        gotoPage(provider.getPageCount() - 1);
        return;
      }
    }
  }

  /**
   * 当前页编辑框事件处理
   * 
   * @author LiQi
   * 
   */
  private class CurrentPageBoxHandler implements ClickHandler, KeyDownHandler {

    public void onClick(ClickEvent event) {
      currentPageBox.selectAll();
    }

    public void onKeyDown(KeyDownEvent event) {
      if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
        try {
          int page = new Integer(currentPageBox.getText()).intValue();

          if (page <= 0)
            page = 1;
          else if (page > provider.getPageCount())
            page = provider.getPageCount();

          gotoPage(page - 1);
        } catch (NumberFormatException e) {
        }

        refreshText();
      }
    }

    private void refreshText() {
      currentPageBox.setText(new Integer(provider.getCurrentPage() + 1).toString());
    }
  }

  /**
   * 每页记录数下拉框事件处理
   * 
   * @author LiQi
   * 
   */
  private class PageSizeBoxHandler implements ChangeHandler {
    public void onChange(ChangeEvent event) {
      pageSizeBox.setFocus(false);

      try {
        int newPageSize = new Integer(pageSizeBox.getItemText(pageSizeBox.getSelectedIndex()))
            .intValue();
        provider.setPageSize(newPageSize);
      } catch (NumberFormatException e) {
        return;
      }

      pageSizeChanged = true;
      provider.setNeedFetch(true);
      gotoPage(0);
    }
  }
}
